import { _decorator, Component, Node } from 'cc'
const { ccclass, property } = _decorator
import { TileMapManage } from '../Tile/TileMapManage'
import { createUINode } from '../../Utils'
import Levels, { ILevel } from '../../Levels'
import DataManage from '../../Runtime/dataManage'
import { TILE_WIDTH } from '../Tile/TileManage'
import EventManage from '../../Runtime/eventManage'
import { DIRECTION_ENUM, ENTITY_STATE_ENUM, ENTITY_TYPE_ENUM, EVENT_ENUM } from '../../Enums'
import { PlayerManage } from '../../Player/PlayerManage'
import { WoodenSkeletonManage } from '../../WoodenSkeleton/WoodenSkeletonManage'
import { DoorManage } from '../../Door/DoorManage'
import { IronSkeletonManage } from '../../IronSkeleton/IronSkeletonManage'
import { BurstManage } from '../../Burst/BurstManage'
import { SpikesManage } from '../../Spikes/SpikesManage'

@ccclass('BattleManage')
export class BattleManage extends Component {
  level: ILevel
  stage: Node

  protected onLoad(): void {
    EventManage.Instance.on(EVENT_ENUM.NEXT_LEVEL, this.nextLevel, this)
    EventManage.Instance.on(EVENT_ENUM.PLAYER_MOVE_END, this.checkArrived, this)
  }
  protected onDestroy(): void {
    EventManage.Instance.off(EVENT_ENUM.NEXT_LEVEL, this.nextLevel)
    EventManage.Instance.off(EVENT_ENUM.PLAYER_MOVE_END, this.checkArrived)
  }

  start() {
    this.generateStage()
    this.initLevel()
  }
  async initLevel() {
    let level = Levels[`level${DataManage.Instance.levelIndex}`]
    if (level) {
      // 初始化时先清空上一个关卡数据
      this.clearLevel()

      this.level = level
      DataManage.Instance.mapInfo = level.mapInfo
      DataManage.Instance.mapRowCount = level.mapInfo.length || 0
      DataManage.Instance.mapColCount = level.mapInfo[0].length || 0
      // 生成地图
      await this.generateTileMap()
      // 生成陷阱
      await this.generateBursts()
      // 生成地刺
      await this.generateSpikes()
      // 生成门
      await this.generateDoor()
      // 创建敌人
      await this.generateEnemies()
      // 创建玩家
      await this.generatePlayer()
    }
  }

  //  下一关
  nextLevel() {
    // 关卡索引+1
    DataManage.Instance.levelIndex++
    this.initLevel()
  }

  clearLevel() {
    this.stage.destroyAllChildren()
    DataManage.Instance.reset()
  }

  // 生成舞台
  generateStage() {
    this.stage = createUINode()
    this.stage.setParent(this.node)
  }
  //   生成地图
  async generateTileMap() {
    // 创建一个地图，并将他添加在舞台下
    let tileMap = createUINode()
    tileMap.setParent(this.stage)
    // 添加 地图控制器组件
    let tileMapManage = tileMap.addComponent(TileMapManage)
    // 初始化地图
    await tileMapManage.init()

    this.adaptPos()
  }

  // 生成玩家
  async generatePlayer() {
    let player = createUINode()
    player.setParent(this.stage)
    const playerManage = player.addComponent(PlayerManage)
    await playerManage.init(this.level.player)
    // 将玩家保存到数据中心
    DataManage.Instance.player = playerManage
    // 玩家初始化时，要派发一个事件，让敌人确定初始化朝向
    EventManage.Instance.emit(EVENT_ENUM.PLAYER_BORN)
  }
  // 创建敌人
  async generateEnemies() {
    const promises = []
    const enemies = this.level.enemies
    for (let i = 0; i < enemies.length; i++) {
      let node = createUINode()
      node.setParent(this.stage)
      let enemyManage = null
      if (enemies[i].type == ENTITY_TYPE_ENUM.WOODEN_SKELETON) {
        enemyManage = node.addComponent(WoodenSkeletonManage)
      } else if (enemies[i].type == ENTITY_TYPE_ENUM.IRON_SKELETON) {
        enemyManage = node.addComponent(IronSkeletonManage)
      }
      promises.push(enemyManage.init(enemies[i]))
      DataManage.Instance.enemies.push(enemyManage)
    }
    await Promise.all(promises)
  }
  // 生成地刺
  async generateSpikes() {
    const promises = []
    const spikes = this.level.spikes
    for (let i = 0; i < spikes.length; i++) {
      let node = createUINode()
      node.setParent(this.stage)
      const spikesManage = node.addComponent(SpikesManage)
      promises.push(spikesManage.init(spikes[i]))
      // 将玩家保存到数据中心
      DataManage.Instance.spikes.push(spikesManage)
    }
    await Promise.all(promises)
  }
  // 生成陷阱
  async generateBursts() {
    const promises = []
    const bursts = this.level.bursts
    for (let i = 0; i < bursts.length; i++) {
      let node = createUINode()
      node.setParent(this.stage)
      const burstManage = node.addComponent(BurstManage)
      promises.push(burstManage.init(bursts[i]))
      // 将玩家保存到数据中心
      DataManage.Instance.bursts.push(burstManage)
    }
    await Promise.all(promises)
  }
  // 生成门
  async generateDoor() {
    let node = createUINode()
    node.setParent(this.stage)
    const doorManage = node.addComponent(DoorManage)
    await doorManage.init(this.level.door)
    // 将玩家保存到数据中心
    DataManage.Instance.door = doorManage
    // 玩家初始化时，要派发一个事件，让敌人确定初始化朝向
    EventManage.Instance.emit(EVENT_ENUM.PLAYER_BORN)
  }

  // 检查玩家是否到达门
  checkArrived() {
    const { x: playerX, y: playerY } = DataManage.Instance.player
    const { x: doorX, y: doorY, state: doorState } = DataManage.Instance.door
    if (playerX == doorX && playerY == doorY && doorState == ENTITY_STATE_ENUM.DEATH) {
      EventManage.Instance.emit(EVENT_ENUM.NEXT_LEVEL)
    }
  }

  // 地图适配屏幕居中
  adaptPos() {
    const { mapRowCount, mapColCount } = DataManage.Instance
    const dixX = (TILE_WIDTH * mapRowCount) / 2
    const dixY = (TILE_WIDTH * mapColCount) / 2 + 80
    this.stage.setPosition(-dixX, dixY)
  }
}
